package com.stylefeng.guns.core.redis;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <pre>
 * 默认缓存业务实现类
 * </pre>
 * 
 * @author zcj Exp
 * @Date 2017年12月6日 下午2:06:04
 * @since 1.0
 */
@Service
public class RedisServiceImpl implements RedisService {

	private String prefix = "";
	/**默认过期时间 秒 1800 是30分钟*/
	private long defaultExpireTime = 1800;
	
	@Resource
	private StringRedisTemplate stringRedisTemplate;

	@Resource
	RedisTemplate<String, Object> redisTemplate; 
	

	@Override
	public void addKeyValue(String key, String value) {
		stringRedisTemplate.opsForValue().set(key, value);
	}

	@Override
	public void addKeyValue(String key, String value, int timeout) {
		stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
	}

	@Override
	public String getValue(String key) {
		return stringRedisTemplate.opsForValue().get(key);
	}

	@Override
	public void deleteValue(String key) {
		stringRedisTemplate.delete(key);
	}

	
	/**
	 * 取得缓存（字符串类型）
	 * @param key
	 * @return
	 */
	@Override
	public String getStr(String key){
		return stringRedisTemplate.boundValueOps(prefix+key).get();
	}
	
	/**
	 * 取得缓存（字符串类型）
	 * @param key
	 * @return
	 */
	@Override
	public String getStr(String key, boolean retain){
		String value = stringRedisTemplate.boundValueOps(prefix+key).get();
		if(!retain){
			redisTemplate.delete(prefix+key);
		}
		return value;
	}
	
	/**
	 * 获取缓存<br>
	 * 注：基本数据类型(Character除外)，请直接使用get(String key, Class<T> clazz)取值
	 * @param key
	 * @return
	 */
	@Override
	public Object getObj(String key){
		return redisTemplate.boundValueOps(prefix+key).get();
	}
	
	/**
	 * 获取缓存<br>
	 * 注：java 8种基本类型的数据请直接使用get(String key, Class<T> clazz)取值
	 * @param key		
	 * @param retain	是否保留
	 * @return
	 */
	@Override
	public Object getObj(String key, boolean retain){
		Object obj = redisTemplate.boundValueOps(prefix+key).get();
		if(!retain){
			redisTemplate.delete(prefix+key);
		}
		return obj;
	}
	
	/**
	 * 获取缓存<br>
	 * 注：该方法暂不支持Character数据类型
	 * @param key	key
	 * @param clazz	类型
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T get(String key, Class<T> clazz) {
		return (T)redisTemplate.boundValueOps(prefix+key).get();
	}
	
	/**
	 * 删除对象
	 */
	@Override
	public void deleteObject(String key) {
		redisTemplate.delete(key);
	}
	
	/**
	 * 根据某一类型查询所有的key
	 * @param pattern
	 * @return
	 */
	@Override
	public Set<String> keysPattern(String pattern) {
		return redisTemplate.keys(pattern);
	}
	
	
	/**
	 * 将value对象写入缓存
	 * @param key
	 * @param value
	 */
	@Override
	public void set(String key,Object value){
		Boolean isString = true;
		if(value.getClass().equals(String.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());				
		}else if(value.getClass().equals(Integer.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Double.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Float.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Short.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Long.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Boolean.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else{
			isString = false;
			redisTemplate.opsForValue().set(prefix+key, value);			
		}
		if(isString){
			stringRedisTemplate.expire(prefix+key, defaultExpireTime, TimeUnit.SECONDS);
		}else {
			redisTemplate.expire(prefix+key, defaultExpireTime, TimeUnit.SECONDS);
		}
	}
	
	/**
	 * 将value对象写入缓存
	 * @param key
	 * @param value
	 * @param time 失效时间(秒)
	 */
	@Override
	public void set(String key,Object value,long time){
		Boolean isString = true;
		if(value.getClass().equals(String.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());				
		}else if(value.getClass().equals(Integer.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Double.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Float.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Short.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Long.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else if(value.getClass().equals(Boolean.class)){
			stringRedisTemplate.opsForValue().set(prefix+key, value.toString());
		}else{
			isString = false;
			redisTemplate.opsForValue().set(prefix+key, value);			
		}
		if(time > 0){
			if(isString){
				stringRedisTemplate.expire(prefix+key, time, TimeUnit.SECONDS);
			}else {
				redisTemplate.expire(prefix+key, time, TimeUnit.SECONDS);
			}
		}else{
			if(isString){
				stringRedisTemplate.expire(prefix+key, defaultExpireTime, TimeUnit.SECONDS);
			}else {
				redisTemplate.expire(prefix+key, defaultExpireTime, TimeUnit.SECONDS);
			}
		}
	}
	
	/**
	 * 发送消息到队列channel中
	 * @param channel
	 * @param message
	 */
	@Override
	public void sendMessage(String channel,Object message) {
		redisTemplate.convertAndSend(channel, message);
	}

	@Override
	public Long getExpire(String key) {
		return redisTemplate.getExpire(key);
	}

	@Override
	public void setForExpire(String key, Object value) {
		Long expire = this.getExpire(key);
		this.set(key,value,expire);
	}
}
